package com.example.demo;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Description : TODO
 * @Author : ZYX
 * @Date : 2022/4/14 10:31
 * @Version : 1.0
 **/
public class TestAtomicLong {

    private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

    // 最后一次令牌发放时间
    public long timeStamp = System.currentTimeMillis();
    // 桶的容量
    private int capacity = 7;
    // 令牌生成速度5/s
    private int rate = 5;
    // 当前令牌数量
    private int tokens;

    public void acquire() {
        //令牌生成速度 = 5/1s   此次时间-上次生成时间=中间耗费时间
        scheduledExecutorService.scheduleWithFixedDelay(() -> {
            long now = System.currentTimeMillis();

            // 生成令牌并加入到桶
            long tokensCal = tokens + (now - timeStamp) * rate/1000;
            int tokenCalInt = (int)tokensCal;
            // 当前令牌数
            tokens = Math.min(capacity,tokenCalInt);
            //每隔0.5秒发送随机数量的请求
            int permits = (int) (Math.random() * 6) + 1;
            System.out.println("请求令牌数：" + permits + "，当前令牌数：" + tokens);
            timeStamp = now;
            if (tokens < permits) {
                // 若不到令牌,则拒绝
                System.out.println("限流了");
            } else {
                // 还有令牌，领取令牌
                tokens -= permits;
                System.out.println("剩余令牌=" + tokens);
            }
        }, 1000, 500, TimeUnit.MILLISECONDS);
        //1秒以后开始执行第一次任务，第一次执行完每隔500ms执行下次任务
    }

    public static void main(String[] args) {
        TestAtomicLong tokensLimiter = new TestAtomicLong();
        tokensLimiter.acquire();
    }

}
